/*
 * SomaFTP.java
 *
 * Created on December 3, 2006, 11:03 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package eu.somatik.somaftp;

import eu.somatik.somaftp.gui.FileSystemPanel;
import eu.somatik.somaftp.gui.MainFrame;
import eu.somatik.somaftp.logic.FileSystemException;
import eu.somatik.somaftp.logic.TransferQueue;
import eu.somatik.somaftp.logic.TransferQueueEntry;
import eu.somatik.somaftp.logic.TransferStatus;
import eu.somatik.somaftp.logic.ftp.FTPFileSystem;
import eu.somatik.somaftp.logic.FileInterface;
import eu.somatik.somaftp.logic.FileSystemInterface;
import eu.somatik.somaftp.logic.FileTransfer;
import eu.somatik.somaftp.logic.local.LocalFileSystem;
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

/**
 *
 * @author francisdb
 */
public class SomaFTP {
    
    private FileSystemInterface fileSystem1;
    private FileSystemInterface fileSystem2;
    
    private TransferQueue queue;
    
    private TrayIcon trayIcon;
    private MainFrame mainFrame;
    
    /** Creates a new instance of SomaFTP */
    public SomaFTP() {
        System.out.println("SomaFTP");
        setFileSystem1(new LocalFileSystem(this));
        
        FTPFileSystem ftp = new FTPFileSystem(this);
        
        ftp.setProperty(FileSystemInterface.PROPERTY_USER, "anonymous");
        ftp.setProperty(FileSystemInterface.PROPERTY_HOST, "ftp.belnet.be");
        ftp.setProperty(FTPFileSystem.PROPERTY_PASSWORD,"test");
        ftp.setProperty(FTPFileSystem.PROPERTY_PORT,"21");
        
        setFileSystem2(ftp);
        
        queue = new TransferQueue();

        startGui();
    }
    
    private void startGui(){
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                prepareSystemTray();
                mainFrame = new MainFrame(SomaFTP.this);
                mainFrame.setIconImage(trayIcon.getImage());
                mainFrame.setVisible(true);
            }
        });
    }
    
    private void prepareSystemTray(){
        if( SystemTray.isSupported()){
            SystemTray tray = SystemTray.getSystemTray();
            ImageIcon icon = new ImageIcon(getClass().getResource("/eu/somatik/somaftp/icons/network-wired.png"));
            Dimension size = tray.getTrayIconSize();
            trayIcon = new TrayIcon(icon.getImage().getScaledInstance(size.width, size.height, Image.SCALE_SMOOTH), "SomaFTP");
            trayIcon.displayMessage("SomaFTP", "Application started", TrayIcon.MessageType.INFO);
            trayIcon.addMouseListener(new MouseAdapter() {
                /**
                 * {@inheritDoc}
                 */
                public void mouseClicked(MouseEvent e) {
                    
                    System.out.println("Action " + e);
                    mainFrame.setVisible(!mainFrame.isVisible());
                }
            });
            
            PopupMenu menu = new PopupMenu();
            MenuItem item = new MenuItem("Exit");
            item.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    mainFrame.dispose();
                    SystemTray.getSystemTray().remove(trayIcon);
                }
            });
            
            menu.add(item);
            trayIcon.setPopupMenu(menu);
            try {
                tray.add(trayIcon);
            } catch (AWTException ex) {
                ex.printStackTrace();
            }
        }else{
            System.out.println("System tray support available.");
        }
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        new SomaFTP();
    }
    
    public FileSystemInterface getFileSystem1() {
        return fileSystem1;
    }
    
    public void setFileSystem1(FileSystemInterface fileSystem1) {
        this.fileSystem1 = fileSystem1;
    }
    
    public FileSystemInterface getFileSystem2() {
        return fileSystem2;
    }
    
    public void setFileSystem2(FileSystemInterface fileSystem2) {
        this.fileSystem2 = fileSystem2;
    }
    
    public void queue(FileInterface[] files){
        TransferQueueEntry entry;        
        FileSystemInterface toFileSystem = null;
        
        for(FileInterface file:files){
            // expecting toFileSystem to be equal for all files
            if(toFileSystem == null && file.getFileSystem().equals(fileSystem1)){
                toFileSystem = fileSystem2;
            }else{
                toFileSystem = fileSystem1;
            }
            
            
            entry = new TransferQueueEntry();
            entry.setDirecory(file.isDirectory());
            
            entry.setFromFile(file.getName());
            entry.setFromPath(file.getFileSystem().getPath());
            entry.setFromProtocol(file.getFileSystem().getProtocol());
            entry.setFromServer(file.getFileSystem().getProperty(FileSystemInterface.PROPERTY_HOST));
            entry.setFromLogin(file.getFileSystem().getProperty(FileSystemInterface.PROPERTY_USER));
            
            entry.setToFile(file.getName());
            entry.setToPath(toFileSystem.getPath());
            entry.setToProtocol(toFileSystem.getProtocol());
            entry.setToLogin(toFileSystem.getProperty(FileSystemInterface.PROPERTY_USER));
            entry.setToServer(toFileSystem.getProperty(FileSystemInterface.PROPERTY_HOST));
            
            getQueue().add(entry);
            
        }
    }
    
    public void transfer(FileInterface file, FileSystemInterface toFileSystem){
           
        FileTransfer transfer = new FileTransfer();
        transfer.setFromFile(file);
        transfer.setToFileSystem(toFileSystem);
        transfer.start();
    }
    
    public void startTransfers(){
        FileInterface file;
        TransferQueueEntry entry;
        FileSystemInterface fromFileSystem = null;
        FileSystemInterface toFileSystem = null;
        boolean done = false;
        while(!done){
            entry = getQueue().getNext();
            if(entry == null){
                done = true;
            }else{
                if(entry.getFromServer() == fileSystem1.getProperty(FileSystemInterface.PROPERTY_HOST)
                    && entry.getFromProtocol() == fileSystem1.getProtocol()){
                    fromFileSystem =fileSystem1;
                }else if(entry.getFromServer() == fileSystem2.getProperty(FileSystemInterface.PROPERTY_HOST)
                    && entry.getFromProtocol() == fileSystem2.getProtocol()){
                    fromFileSystem = fileSystem2;
                }else{
                    entry.setStatus(TransferStatus.FAILED);
                }
                
                if(entry.getToServer() == fileSystem1.getProperty(FileSystemInterface.PROPERTY_HOST)
                    && entry.getToProtocol() == fileSystem1.getProtocol()){
                    toFileSystem =fileSystem1;
                }else if(entry.getToServer() == fileSystem2.getProperty(FileSystemInterface.PROPERTY_HOST)
                    && entry.getToProtocol() == fileSystem2.getProtocol()){
                    toFileSystem = fileSystem2;
                }else{
                    entry.setStatus(TransferStatus.FAILED);
                }
                
                System.out.println("from = "+fromFileSystem.getClass().getSimpleName() +" "+entry.getFromServer());
                System.out.println("to = "+toFileSystem.getClass().getSimpleName() +" "+entry.getToServer());

                fromFileSystem.changeDirectory(entry.getFromPath());
                toFileSystem.changeDirectory(entry.getToPath());
                
                
                file = fromFileSystem.getFileObjectFor(entry.getFromFile());
                
                if(entry.isDirectory()){
                    toFileSystem.mkdir(entry.getFromFile());
                    toFileSystem.changeDirectory(entry.getFromFile());
                    fromFileSystem.changeDirectory(entry.getFromFile());
                    List<FileInterface> files = fromFileSystem.list(false);
                    queue(files.toArray(new FileInterface[files.size()]));
                }else{
                    transfer(file, toFileSystem);
                }
                entry.setStatus(TransferStatus.FINISHED);
                getQueue().remove(entry);
            }
        }
    }

    public TransferQueue getQueue() {
        return queue;
    }
    
}
